package passworks;

import java.util.ArrayList;
import java.util.List;
import passworks.Gates.*;

public class Model {

    public List<GateBase> gates;
    public List<Wire> wires;
    public List<GeneratorBase> sources;
    // private List<DrawBase> drawables;    Meg nincs grafika
    
    public Model() {
        gates = new ArrayList<GateBase>();
        wires = new ArrayList<Wire>();
        sources = new ArrayList<GeneratorBase>();
    }

    public void Simulate() {

        Logger.Print("Model", "Simulate", Direction.IN, -1);

        List<GateBase> actGates = new ArrayList<GateBase>();
        Logger.Print("Model.actGates", "List<GateBase>", Direction.SINGLE, -1);

        /*
         * Wirek instabilra allitasa
         */
        for(Wire w : wires) {
            w.SetStable(false);
        }

        GateBase.checkStable = true;

        /*
         * Vegigiteralas a sources-en (elso kor)
         */
        for(GeneratorBase gb : sources) {
            gb.Handle(actGates);
        }
        
        GateBase.checkStable = false;

        /*
         * Amig az actGates nem ures, vagy nincs exception
         */
        while(!actGates.isEmpty()) {
            actGates.get(0).Handle(actGates);
        }
        // (utemezo leptetese) szekvencia diagrammon szemleletes celjabol
        Logger.Print("actGates", "isEmpty", Direction.SINGLE, -1);

        /*
         * Minden forrasra ami nem switchable nextState hivas a vegen
         */
        for(GeneratorBase gb : sources) {
            if (!gb.switchable)
                gb.NextState();
        }

        Logger.Print("Model","Simulate",Direction.OUT,-1);
    }

    // Most meg nincs fajlozas, csak tesztet epiti fel
    public /*List<DrawBase>*/ void CreateCircuit(/*List<String> source*/) {

        /*
         * Szkeleton miatt "beegetve" az implementacio elkerulesenek erdekeben
         *
         *  switch1 [O]---wire1----\__  (OR)
         *                          )_)-----wire3-----O LED
         *  switch2 [0]---wire2----/
         *
         */

        Logger.Print("Model", "CreateCircuit", Direction.IN, -1);

        Switch switch1 = new Switch(false);
        Logger.Print("Model.gates", "add", Direction.SINGLE, -1);
        Logger.Print("Model.sources", "add", Direction.SINGLE, -1);

        Switch switch2 = new Switch(false);
        Logger.Print("Model.gates", "add", Direction.SINGLE, -1);
        Logger.Print("Model.sources", "add", Direction.SINGLE, -1);
        
        OR or = new OR();
        Logger.Print("Model.gates", "add", Direction.SINGLE, -1);

        Wire wire1 = new Wire(or);
        Logger.Print("Model.wires", "add", Direction.SINGLE, -1);

        switch1.AddOutput(wire1);
        or.AddInput(wire1);

        Wire wire2 = new Wire(or);
        Logger.Print("Model.wires", "add", Direction.SINGLE, -1);
        
        switch2.AddOutput(wire1);
        or.AddInput(wire2);

        LED led = new LED();
        Logger.Print("Model.gates", "add", Direction.SINGLE, -1);

        Wire wire3 = new Wire(led);
        Logger.Print("Model.wires", "add", Direction.SINGLE, -1);

        led.AddInput(wire3);
        or.AddOutput(wire3);

        Logger.Print("Model", "CreateCircuit", Direction.OUT, -1);
        
    }

    public void ResetCircuit() {
        Logger.Print("Model", "ResetCircuit", Direction.IN, -1);

        for(Wire w : wires) {
            w.SetState(false);
            w.SetStable(false);
        }
        for(GateBase gb : gates) {
            gb.Init();
        }

        Logger.Print("Model", "ResetCircuit", Direction.OUT, -1);
    }
    // public void SetSwitch(int ID) {} Egyelore kihagyjuk, tudjuk referenciat
}
